home *** CD-ROM | disk | FTP | other *** search
- #include "header.h"
-
- extern DirectDraw *DD;
- extern unsigned char Darkness[33][256];
-
- inline int LeftSection();
- inline int RightSection();
- int shl10idiv(int x, int y);
- void InnerLoop(char *Screen, char *Bitmap, int u, int v, int c, int width);
- int CalcGVect(POLYGON *p);
-
- // Some globals to interface with the left and right section functions
- VERTEX *lva[3], *rva[3];
- FPOINT *lpa[3], *rpa[3];
- int ls, rs, lsh, rsh;
- int lu, dlu, lv, dlv, lc, dlc;
- int lx, dlx, rx, drx;
- int dudx, dvdx, dcdx;
-
- int WORLD::DrawTriangle(POLYGON *p, void *Screen)
- {
- VERTEX *v1, *v2, *v3, *tv;
- FPOINT *p1, *p2, *p3, *tp;
- int height, temp, longest;
- char *scrptr, *scrtemp;
- int x1, width, index;
- int u, v, ys, ye, i, c;
- char *bitmap;
-
- CalcGVect(p);
- v1 = &p->Vertex[0]; v2 = &p->Vertex[1]; v3 = &p->Vertex[2];
- p1 = &p->TextPt[0]; p2 = &p->TextPt[1]; p3 = &p->TextPt[2];
-
- if(v1->sy > v2->sy)
- {
- tv = v1; v1 = v2; v2 = tv;
- tp = p1; p1 = p2; p2 = tp;
- }
- if(v1->sy > v3->sy)
- {
- tv = v1; v1 = v3; v3 = tv;
- tp = p1; p1 = p3; p3 = tp;
- }
- if(v2->sy > v3->sy)
- {
- tv = v2; v2 = v3; v3 = tv;
- tp = p2; p2 = p3; p3 = tp;
- }
-
- height = v3->sy - v1->sy;
- if(!height) return 0;
- temp = ((v2->sy - v1->sy) << 16) / height;
- longest = temp * (v3->sx - v1->sx) + ((v1->sx - v2->sx) << 16);
- if(!longest) return 0;
-
- // Vertices now sorted and the length of the longest scanline is calculated
-
- if(longest < 0)
- {
- rva[0] = v3; rva[1] = v2; rva[2] = v1; rs = 2;
- lva[0] = v3; lva[1] = v1; ls = 1;
- rpa[0] = p3; rpa[1] = p2; rpa[2] = p1;
- lpa[0] = p3; lpa[1] = p1;
-
- if(LeftSection() <= 0)
- return 0;
- if(RightSection() <= 0)
- {
- rs--;
- if(RightSection() <= 0)
- return 0;
- }
- if(longest > -0x1000) longest = -0x1000;
- }
-
- else
- {
- lva[0] = v3; lva[1] = v2; lva[2] = v1; ls = 2;
- rva[0] = v3; rva[1] = v1; rs = 1;
- lpa[0] = p3; lpa[1] = p2; lpa[2] = p1;
- rpa[0] = p3; rpa[1] = p1;
-
- if(RightSection() <= 0)
- return 0;
- if(LeftSection() <= 0)
- {
- ls--;
- if(LeftSection() <= 0)
- return 0;
- }
- if(longest < 0x1000) longest = 0x1000;
- }
-
- dudx = shl10idiv(temp * (p3->x - p1->x) + ((p1->x - p2->x) << 16),
- longest);
- dvdx = shl10idiv(temp * (p3->y - p1->y) + ((p1->y - p2->y) << 16),
- longest);
- dcdx = shl10idiv(temp * (v3->Vect - v1->Vect) + ((v1->Vect - v2->Vect) << 16),
- longest);
- ys = v1->sy; ye = v3->sy;
- if(ye > 416) ye = 416;
- scrptr = (char *)Screen + ys * DD->Pitch;
- bitmap = (char *)Texture[0].Data + ((p->Texture - 1) << 5);
- for(i = ys; i < ye; i++)
- {
- // Find and clip the scanlines
- if(i >= 0)
- {
- u = lu; v = lv;
- c = lc;
- x1 = lx >> 16;
-
- if(x1 < 0)
- {
- while(x1 < 0)
- {
- u += dudx;
- v += dvdx;
- c += dcdx;
- x1++;
- }
- }
- width = (rx >> 16) - x1;
- if((x1 + width) > 640)
- width -= (x1 + width) - 640;
- scrtemp = scrptr + x1;
-
- if(width > 0)
- InnerLoop(scrtemp, bitmap, u, v, c, width);
- }
-
- scrptr += DD->Pitch;
-
- if(--lsh <= 0)
- {
- if(--ls <= 0) return 0;
- if(LeftSection() <= 0)
- return 0;
- }
- else
- {
- lx += dlx; lu += dlu; lv += dlv; lc += dlc;
- }
-
- if(--rsh <= 0)
- {
- if(--rs <= 0) return 0;
- if(RightSection() <= 0)
- return 0;
- }
- else
- {
- rx += drx;
- }
- }
-
- return 0;
- };
-
- inline int LeftSection()
- {
- VERTEX *v1, *v2;
- FPOINT *p1, *p2;
- int height;
-
- v1 = lva[ls]; v2 = lva[ls - 1];
- p1 = lpa[ls]; p2 = lpa[ls - 1];
- height = v2->sy - v1->sy;
- if(!height) return 0;
-
- dlx = ((v2->sx - v1->sx) << 16);
- lx = v1->sx << 16;
- dlu = ((p2->x - p1->x) << 16);
- lu = p1->x << 16;
- dlv = ((p2->y - p1->y) << 16);
- lv = p1->y << 16;
- dlc = ((v2->Vect - v1->Vect) << 16);
- lc = v1->Vect << 16;
- if(height == 2) { dlx >>= 1; dlu >>= 1; dlv >>= 1; dlc >>= 1;}
- else if(height == 4) { dlx >>= 2; dlu >>= 2; dlv >>= 2; dlc >>= 2;}
- else if(height == 8) { dlx >>= 3; dlu >>= 3; dlv >>= 3; dlc >>= 3;}
- else { dlx /= height; dlu /= height; dlv /= height; dlc /= height;}
- lsh = height;
- return height;
- };
-
- inline int RightSection()
- {
- VERTEX *v1, *v2;
- int height;
-
- v1 = rva[rs]; v2 = rva[rs - 1];
- height = v2->sy - v1->sy;
- if(!height) return 0;
-
- drx = ((v2->sx - v1->sx) << 16) / height;
- rx = v1->sx << 16;
- rsh = height;
- return height;
- };
-
- void InnerLoop(char *Screen, char *Bitmap, int u, int v, int c, int width)
- {
- do
- {
- *Screen++ = Darkness[c >> 16][*(Bitmap + ((v >> 16) << 9) + (u >> 16))];
- u += dudx;
- v += dvdx;
- c += dcdx;
- } while(--width);
- };
-
- #pragma aux shl10idiv = \
- "mov edx, eax"\
- "sar edx, 16"\
- "shl eax, 16"\
- "idiv ebx"\
- "shld edx, eax, 16"\
- parm [eax][ebx]\
- modify exact [eax edx]\
- value [eax]
-
- int CalcGVect(POLYGON *p)
- {
- float src;
- float dist;
- int tmp, i, j;
-
- for(i = 0; i < p->Number_Vertices; i++)
- {
- dist = p->Vertex[i].vz;
- tmp = (int)(dist - 4096.0);
- if(tmp < 0) tmp = 0;
- tmp >>= 8;
- j = p->Vertex[i].Vect - tmp;
- if(j < 0) j = 0;
- p->Vertex[i].Vect = j;
- }
-
- return(0);
- };
-
-